package application;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import resources.ImageLoader;
import sound.GameSound;
import sound.Player;
import universe.Game;
import display.GameDataDisplay;
import display.GameDisplay;
import display.Utils;
import files.TetrisData;

public class Tetris implements Observer{

	// Configuration personnelle du joueur :
	private TetrisData theTetrisData;

	private Game theGame;
	@SuppressWarnings("unused")
	private GameDisplay theGameDisplay;
	@SuppressWarnings("unused")
	private GameDataDisplay theGameDataDisplay;
	private JFrame 	theFrame;

	private Container 	theContainerGame;
	private Container 	theContainerGameData;
	private BackgroundPanel gameBackgroundPanel;


	private Thread gameThread;

	@SuppressWarnings("unused")
	private GameSound  theGameSound;
	private Player homeMenuSound;
	private Player scorePanelSound;
	//public boolean soundPaused = false;

	private TetrisMenuBar theTetrisMenuBar;
	private BackgroundPanel theHomeMenu;
	private BackgroundPanel theScoresPanel;

	private KeyTetris 	 keyListener;
	private ActionTetris actionListener;
	private JComboBox selectPlayer;
	private JLabel labelScores;


	public Tetris() {


		theFrame = new JFrame();
		theFrame.setResizable(false);
		// Listener pour la frame :
		theFrame.addWindowListener(new WindowListener() {

			@Override
			public void windowOpened(WindowEvent e) {}
			@Override
			public void windowIconified(WindowEvent e) {}
			@Override
			public void windowDeiconified(WindowEvent e) {}
			@Override
			public void windowDeactivated(WindowEvent e) {}
			@Override
			public void windowClosing(WindowEvent e) {
				saveXMLFile();
			}
			@Override
			public void windowClosed(WindowEvent e) {}
			@Override
			public void windowActivated(WindowEvent e) {}
		});

		theFrame.setSize(display.Utils.getFrameWidthPx(), display.Utils.getFrameHeightPx());
		theFrame.setTitle(application.Utils.frameTitle);
		theFrame.setLayout(new BorderLayout());
		//theFrame.setResizable(false);
		theFrame.setLocationRelativeTo(null);
		theFrame.setDefaultCloseOperation(3);
		theFrame.setIconImage(ImageLoader.chargeImage(display.Utils.iconFrameImage));

		// Chargement des préférences
		loadXMLFile();

		//BARRE DE MENU
		this.theTetrisMenuBar = new TetrisMenuBar(this);
		theFrame.setJMenuBar(this.getTetrisMenuBar());  

		//LISTENER
		keyListener = new KeyTetris(this);
		actionListener = new ActionTetris(this);		

		theFrame.addKeyListener(this.getKeyListener());

		/* Affichage des keyListener
		KeyListener[] list = theFrame.getKeyListeners();
		for (KeyListener keyListener : list) {
			System.out.println(keyListener.toString());
		}*/

		gameBackgroundPanel = new BackgroundPanel(display.Utils.gameBackgroundImage);
		gameBackgroundPanel.setLayout(new BorderLayout());

		theContainerGame = new Container();
		theContainerGameData = new Container();
		theContainerGame.setSize(display.Utils.gameDisplayWidth, display.Utils.gameDisplayHeight);
		theContainerGameData.setPreferredSize(new Dimension(display.Utils.gameDataDisplayWidth, display.Utils.gameDataDisplayHeight));
		gameBackgroundPanel.add(theContainerGame, BorderLayout.CENTER);
		gameBackgroundPanel.add(theContainerGameData, BorderLayout.EAST);

		this.newHomeMenu();
		this.showHomeMenu();
		this.newScorePanel();
		


		

		theFrame.setVisible(true);
		theFrame.requestFocus();

		//theFrame.repaint();
	}

	public void reloadComboPlayers(){
		String pLoop = "";
		String pCurrent = getTheTetrisData().getPlayer();
		
		
		selectPlayer.removeAllItems();

		
		
		for(int i = 0; i < getTheTetrisData().getPlayers().size(); i++){
			pLoop = getTheTetrisData().getPlayers().get(i);
			selectPlayer.addItem(pLoop);
			
			if(pLoop == pCurrent){
				selectPlayer.setSelectedIndex(i);
				
			}
			
		}
		theTetrisData.setPlayer(pCurrent);
	}

	public void selectCurrentPlayerInCombo(){;
		if(selectPlayer != null){
			for(int i = 0; i < getTheTetrisData().getPlayers().size(); i++){
				if(getTheTetrisData().getPlayers().get(i).equals(getTheTetrisData().getPlayer())) 
					selectPlayer.setSelectedIndex(i);
			}
		}
	}

	public void closeFrame(){
		this.theFrame.dispose();
	}

	public JFrame getFrame() {
		return theFrame;
	}

	public TetrisMenuBar getTetrisMenuBar() {
		return theTetrisMenuBar;
	}

	public ActionTetris getActionListener(){
		return this.actionListener;
	}

	public KeyTetris getKeyListener(){
		return this.keyListener;
	}

	/** **************************************** */


	public void loadXMLFile(){
		try {
			theTetrisData = (TetrisData) files.XMLTools.decodeFromFile(application.Utils.fileName);
		} catch (FileNotFoundException e) {
			//e.printStackTrace();
		} catch (IOException e) {
			//e.printStackTrace();
		}

		if(theTetrisData == null)
			theTetrisData = new TetrisData();

		theTetrisData.loadAll();

		//System.out.println("TetrisData chargé.");
		//System.out.println(application.Utils.getThemes().size() + " thèmes existant(s).");
		//System.out.println("Thème choisi : " + application.Utils.themeChoosen);

		//System.out.println("Scores précédents :");
		for(int i =0; i < application.Utils.getScores().size(); i++){
			//System.out.println(application.Utils.getScores().get(i).getPlayer() + " - " + application.Utils.getScores().get(i).getScore());
		}

	}

	public void saveXMLFile(){

		if(theGame != null){
			// Enregistrement du score :
			theTetrisData.setScore(theGame.getScore());
		}
		theTetrisData.saveAll();

		try {
			files.XMLTools.encodeToFile(theTetrisData, application.Utils.fileName);
			//System.out.println("Sauvegarde des données");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}



	public TetrisData getTheTetrisData() {
		return theTetrisData;
	}
	
	/**
	 * SCORE PANEL
	 */
	private void newScorePanel(){
		//Création du panel avec une image de fond sur lequel on dispose les boutons
		theScoresPanel = new BackgroundPanel(display.Utils.topScoresImage);
		theScoresPanel.setLayout(null);
		theScoresPanel.setBackground(Color.WHITE);
		
		JPanel myPanel = new JPanel();
		myPanel.setBounds(display.Utils.getFrameWidthPx()/4, 0, display.Utils.getFrameWidthPx()/2, display.Utils.getFrameHeightPx());
		myPanel.setBackground(new Color(255,255,255,150));
		theScoresPanel.add(myPanel);
		
		//Création des boutons
		labelScores = new JLabel(theTetrisData.getScoreHTML(),SwingConstants.CENTER);
		labelScores.setFont(new Font("ARIAL", Font.BOLD, 20));
		labelScores.setForeground(Color.BLACK);
		labelScores.setBounds(0, 0, Utils.getFrameWidthPx(), 300);

		labelScores.setAlignmentY(JLabel.CENTER_ALIGNMENT);
		labelScores.setBackground(Color.GRAY);
		//labelScores.setAlignmentX(JLabel.CENTER_ALIGNMENT);

		//labelScores.setBounds((Utils.getFrameWidthPx()/2)-40, (Utils.getFrameHeightPx()/2)-80, 80, 30);
				
		myPanel.add(labelScores);
		
		//MUSIQUE DE FIN
		this.scorePanelSound = new Player(sound.Utils.scorePanelTone, true);
		
		//homeMenuSound.resume();
		
	}
	
	private void updateScorePanel(){
		labelScores.setText(theTetrisData.getScoreHTML());
	}
	

	/**
	 * HOME MENU
	 */
	private void newHomeMenu(){
		//Création du panel avec une image de fond sur lequel on dispose les boutons
		theHomeMenu = new BackgroundPanel(display.Utils.homeMenuBackgroundImage);
		theHomeMenu.setStretch(false);
		theHomeMenu.setLayout(null);

		//Création des boutons
		JButton buttonPlay = new JButton(application.Utils.buttonPlay);
		JButton buttonConfig = new JButton(application.Utils.buttonConfig);
		JCheckBox boxSound = new JCheckBox(application.Utils.boxSound);

		selectPlayer = new JComboBox();
		reloadComboPlayers();

		JButton buttonNewPlayer = new JButton(application.Utils.buttonNewPlayer);

		//	selectPlayer.setSelectedItem(sound.Utils.gameBackgroundTone);

		//if(application.Utils.soundActivated) boxSound.setSelected(true);

		boxSound.setOpaque(false);
		//Color theColor = new Color(display.Utils.soundBoxHomeMenuColor.getRed(),display.Utils.soundBoxHomeMenuColor.getGreen(),display.Utils.soundBoxHomeMenuColor.getBlue(),display.Utils.soundBoxHomeMenuAlpha);
		//boxSound.setBackground(theColor);
		boxSound.setForeground(display.Utils.soundBoxHomeMenuFontColor);

		//PLACEMENT DES BOUTONS
		buttonPlay.setBounds((Utils.getFrameWidthPx()/2)-40, (Utils.getFrameHeightPx()/2)-80, 80, 30);
		buttonConfig.setBounds((Utils.getFrameWidthPx()/2)-75, (Utils.getFrameHeightPx()/2)-30, 150, 30);
		boxSound.setBounds((Utils.getFrameWidthPx()/2)-25, (Utils.getFrameHeightPx()/2)+20,50,30);
		selectPlayer.setBounds((Utils.getFrameWidthPx())-160, 0, 150, 30);
		buttonNewPlayer.setBounds((Utils.getFrameWidthPx())-160, 30, 150, 30);

		//AJOUT DES BOUTONS AU MENU D'ACCUEIL		
		theHomeMenu.add(buttonPlay);
		theHomeMenu.add(buttonConfig);
		theHomeMenu.add(boxSound);
		theHomeMenu.add(selectPlayer);
		theHomeMenu.add(buttonNewPlayer);

		//AJOUT DES LISTENERS
		buttonPlay.addActionListener(this.getActionListener());
		buttonConfig.addActionListener(this.getActionListener());
		boxSound.addActionListener(this.getActionListener());
		selectPlayer.addActionListener(this.getActionListener()); 
		buttonNewPlayer.addActionListener(this.getActionListener()); 

		selectCurrentPlayerInCombo();
		//System.out.println(theTetrisData.getPlayer());

		//MUSIQUE D'ACCUEIL
		this.homeMenuSound = new Player(sound.Utils.homeMenuTone, true);
	}

	public void showHomeMenu(){
		if(theGame !=null){
			//System.out.println("Tetris.showHomeMenu : pré-killGame");
			killGame();
			//System.out.println("Tetris.showHomeMenu : post-killGame");
		}
		this.hideScorePanel();
		//MAJ DE LA CHECKBOX
		for(int i = 0; i < this.getHomeMenu().getComponents().length; i++){
			if(this.getHomeMenu().getComponent(i) instanceof JCheckBox){
				JCheckBox chkbox = (JCheckBox) this.getHomeMenu().getComponent(i);
				if(application.Utils.soundActivated){
					chkbox.setSelected(true);
				}
				else{
					chkbox.setSelected(false);
				}
			}
		}
		
		
		//LECTURE MUSIQUE
		if(application.Utils.soundActivated){
			this.homeMenuSound.resume();
		}
		
		//AJOUT DU MENU D'ACCUEIL A LA FRAME
		theFrame.add(theHomeMenu, BorderLayout.CENTER);
		this.theHomeMenu.setVisible(true);	
		theFrame.requestFocusInWindow();
	}
	
	
	public void showScorePanel(){
		if(theGame !=null){
			//System.out.println("Tetris.showHomeMenu : pré-killGame");
			killGame();
			//System.out.println("Tetris.showHomeMenu : post-killGame");
		}
		this.hideHomeMenu();
		
		updateScorePanel();

		
		//LECTURE MUSIQUE
		if(application.Utils.soundActivated){
			this.scorePanelSound.resume();
		}
		
		//AJOUT DU MENU D'ACCUEIL A LA FRAME
		theFrame.add(theScoresPanel, BorderLayout.CENTER);
		this.theScoresPanel.setVisible(true);	
		//theFrame.requestFocusInWindow();
		theFrame.setSize(display.Utils.getFrameWidthPx()+1, display.Utils.getFrameHeightPx());
		theFrame.setSize(display.Utils.getFrameWidthPx(), display.Utils.getFrameHeightPx());
		theFrame.requestFocusInWindow();
		theFrame.repaint();

	}
	
	public void hideScorePanel(){
		if(this.theScoresPanel != null){
			this.theScoresPanel.setVisible(false);
			this.getFrame().remove(theScoresPanel);
	
			//ARRET MUSIQUE
			if(this.scorePanelSound instanceof Player){
				//System.out.println("hideHomeMenu : on stop la musique HomeMenusound");
				this.scorePanelSound.stop();
			}
		}
	}

	public void hideHomeMenu(){
		if(this.theHomeMenu != null){
			this.theHomeMenu.setVisible(false);
			this.getFrame().remove(theHomeMenu);
	
			//ARRET MUSIQUE
			if(this.homeMenuSound instanceof Player){
				//System.out.println("hideHomeMenu : on stop la musique HomeMenusound");
				this.homeMenuSound.stop();
			}
		}
	}
	/** **************************************** */




	/**
	 * RELATED TO GAME
	 */
	public void newGame(){
		if(this.theHomeMenu.isVisible()){
			hideHomeMenu();
		}
		if(this.theScoresPanel.isVisible()){
			hideScorePanel();
		}
		if(theGame !=null){
			killGame();
		}

		theFrame.add(gameBackgroundPanel, BorderLayout.CENTER);
		theFrame.requestFocusInWindow();

		theGame = new Game();
		theGame.addObserver(this);
		gameThread = new Thread(theGame,"Tetris.gameThread");
		this.theGameDisplay = new GameDisplay(theContainerGame, theGame);
		this.theGameDataDisplay = new GameDataDisplay(theContainerGameData, theGame);
		theGameSound = new GameSound(theGame);

		theFrame.requestFocus();
		//theFrame.repaint();

		@SuppressWarnings("unused")
		Thread tPaint = new Thread() {
			public void run(){
				theFrame.repaint();
			}
		};

		//playSound();
		gameThread.start();
	}

	public void killGame(){

		//System.out.println("on va tout tuer!!!!!");
		if(this.getGame() != null){
			this.theGame.setAlive(false);
			this.theGame.deleteObserver(this);
			this.theGame.stop();
			
			//System.out.println("avant le =null > theGame="+theGame);
			this.theGame = null;
			//System.out.println("apres le =null > theGame="+theGame);
			

			
			this.theContainerGame.removeAll();
			this.theContainerGameData.removeAll();

			this.getFrame().remove(gameBackgroundPanel);


			//this.theGameDisplay.clear();
			//this.theGameDataDisplay.removeAll();

		//	System.out.println("fin de killGame");
		}
		else{
		//	System.err.println("Y'a pas de game");
		}
		

	}

	public void togglePause(){
		if(this.theGame != null){
			this.theGame.togglePause();
		}
		else {
			//System.out.println("il n'y a pas de Game en cours");
		}
	}

	public boolean isGamePaused(){
		boolean returned = true;
		if(this.theGame != null){
			returned = this.theGame.isGamePaused();
		}
		return returned;
	}

	public Game getGame(){
		return this.theGame;
	}

	public Player getHomeMenuSound() {
		return homeMenuSound;
	}

	public BackgroundPanel getHomeMenu() {
		return theHomeMenu;
	}

	public void setHomeMenu(BackgroundPanel pHomeMenu) {
		this.theHomeMenu = pHomeMenu;
	}

	@Override
	public void update(Observable o, Object arg) {
	
		if(arg.equals("GAME_OVER")){
			// Sauvegarde du fichier
			saveXMLFile();
			loadXMLFile();
			
			killGame();
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			//theFrame.removeAll();
			//this.newScorePanel();
			
			this.showScorePanel();
			
			
			
			theFrame.setSize(Utils.getFrameWidthPx()+1, Utils.getFrameHeightPx());
			theFrame.setSize(Utils.getFrameWidthPx(), Utils.getFrameHeightPx());
			//theFrame.repaint();
			
			
		}
		
	}

	/*
	public void playSound(){
		homeMenuSound = new Player(sound.Utils.backgroundTone, true);

		if(this.theGame != null && application.Utils.soundActivated){
			homeMenuSound.start();
		}
	}

	public Player getHomeMenuSound() {
		return homeMenuSound;
	}

	//@dedicace à Bobby Valentin
	public void setHomeMenuSound(Player pHomeMenuSound) {
		this.homeMenuSound = pHomeMenuSound;
	}*/
	/** **************************************** */



}